#include <iostream>
using namespace std;

//普通员工
class Employee {
public:
	//构造函数
	Employee (const string& name, int id, int grade)
		:m_name(name), m_id(id), m_grade(grade) {}
	
	//打印员工信息
	void printInfo (void) {
		printBasic (); //打印基本信息
		printExtra (); //打印特有信息
	}
	//计算薪酬
	void paySalay (void) {
		double salary = calBasic() + calMerit();
		cout << "薪资为:" << salary << endl; 
	}
private:
	void printBasic (void) {
		cout << "姓名" << m_name << endl;
		cout << "工号" << m_id << endl;
		cout << "职位级别" << m_grade << endl;
	}
	virtual void printExtra (void) {
		cout << "职位:普通员工" << endl;
	}
	double calBasic (void) {
		cout << "输入出勤天数:";
		int attend; 
		cin >> attend;
		m_attend = attend / 23.0;
		m_basic = s_grades[m_grade-1] * m_attend;
		return m_basic;
	}
	virtual double calMerit (void) {
		return m_basic / 2; 
	}
protected:
	double m_attend; //出勤率
private:
	string m_name;//姓名
	int m_id; //工号
	int m_grade; //职位等级
	static double s_grades[6]; //职级薪资表
	double m_basic; //基本工资
};

double Employee::s_grades[] = {
	5000, 6000, 7000, 10000, 12000, 15000
};

//技术员
class Technician:virtual public Employee {
public:
	Technician (const string& name, int id, int grade, double allow)
		:Employee(name, id, grade),m_allow(allow) {}
protected:
	void printExtra (void) {
		cout << "职位：技术员" << endl;
		cout << "研发津贴:" << m_allow << endl;
	}
	double calMerit (void) {
		cout << "输入进度因素:";
		double factor;
		cin >> factor; 
		//小时数*研发津贴*进度因素
		return 8*23*m_attend*m_allow*factor;
	}
private:
	double m_allow;
};


//绩效奖金
class Manager:virtual public Employee{
public:
	Manager (const string& name, int id, int grade, double bouns)
		:Employee(name, id, grade), m_bouns(bouns) {}
protected:
	void printExtra (void) {
		cout << "职位:经理" << endl;
		cout << "绩效奖金:" << m_bouns << endl;
	}
	double calMerit (void) {
		cout << "输入绩效因数:" << endl;
		double factor;
		cin >> factor;
		return m_bouns*factor;
	}
private:
	double m_bouns; //绩效奖金
};

//技术主管
class TechManager:public Technician, public Manager {
public:
	TechManager (const string& name, int id, int grade, double allow, double bouns):
		Technician (name, id, grade, allow), 
		Manager(name, id, grade, bouns), 
		Employee(name, id, grade) {}
private:
	void printExtra (void) {
		Technician::printExtra ();
		Manager::printExtra();
	}
	double calMerit (void) {
		return (Technician::calMerit() + Manager::calMerit())/2;
	}
};

int main (void)
{
	Employee emp("张飞", 10011, 2);
	emp.printInfo ();
	emp.paySalay ();

	Technician tech("诸葛亮", 10012, 4, 30);
	tech.printInfo ();
	tech.paySalay ();
	
	Manager manager("刘备", 10001, 6, 5000);
	manager.printInfo ();
	manager.paySalay ();

	TechManager techmanager ("刘禅", 10013, 6, 35, 6000);
	techmanager.printInfo ();
	techmanager.paySalay ();

	return 0;
}
